﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OcenyOpisowe.Core.Data;

namespace OcenyOpisowe.Core.Repositories
{
	/// <summary>
	/// Repozytorium nauczycieli. Pozwala na pobieranie danych nauczycieli z bazy danych i zwracanie ich
	/// w formie widoków modeli oraz zapisywanie zmodyfikowanych danych do bazy.
	/// </summary>
	internal class TeachersRepository : ITeachersRepository
	{
		#region Publiczne właściwości klasy
		/// <summary>
		/// Pobiera pracownika po identyfikatorze.
		/// </summary>
		/// <param name="identifier">Identyfikator pracownika do pobrania.</param>
		/// <returns>Pobrany pracownik.</returns>
		public Teacher this[int identifier]
		{
			get { return _databaseContext.Teachers.Single(teacher => teacher.TeacherID == identifier); }
		}
		#endregion

		#region Prywatne zmienne klasy
		/// <summary>
		/// Kontekst bazy danych służący do zarządzania obiektami bazodanowymi.
		/// W tym wypadku chodzi o zarządzanie nauczycielami.
		/// </summary>
		private readonly Entities _databaseContext;
		#endregion

		#region Konstruktor klasy
		/// <summary>
		/// Inicjuje instancję repozytorium nauczycieli.
		/// </summary>
		public TeachersRepository()
		{
			_databaseContext = new Entities();
		}
		#endregion

		#region Metoda Add
		/// <summary>
		/// Metoda dodająca nowego pracownika do repozytorium.
		/// </summary>
		/// <param name="teacher">Pracownik do dodania.</param>
		public void Add(Teacher teacher)
		{
			teacher.CreateDate = DateTime.Now;
			teacher.UpdateDate = DateTime.Now;
			_databaseContext.Teachers.AddObject(teacher);
			_databaseContext.SaveChanges();
		}
		#endregion

		#region Metoda Delete
		/// <summary>
		/// Metoda usuwająca nauczyciela z bazy danych nauczycieli.
		/// </summary>
		/// <param name="teacher">Nauczyciel do usunięcia z bazy danych.</param>
		public void Delete(Teacher teacher)
		{
			_databaseContext.Teachers.DeleteObject(teacher);
			_databaseContext.SaveChanges();
		}
		#endregion

		#region Metoda FindTeacherByLogin
		/// <summary>
		/// Metoda wyszukująca pracownika po loginie.
		/// </summary>
		/// <param name="teacherLogin">Login pracownika do znalezienia.</param>
		public Teacher FindTeacherByLogin(string teacherLogin)
		{
			return _databaseContext.Teachers.SingleOrDefault(teacher => teacher.Login == teacherLogin);
		}
		#endregion

		#region Metoda GetAllTeachers
		/// <summary>
		/// Metoda pobierająca wszystkich pracowników dodanych do bazy danych szkoły.
		/// </summary>
		/// <returns>Kolekcja wszystkich pracowników dodanych do bazy danych szkoły.</returns>
		public IEnumerable<Teacher> GetAllTeachers()
		{
			return _databaseContext.Teachers.AsEnumerable();
		}
		#endregion

		#region Metoda Update
		/// <summary>
		/// Metoda zapisująca dane nauczyciela na bazę danych. Nie dodaje ona nowych nauczycieli
		/// lecz tylko nadpisuje dane istniejącego nauczyciela o tym samym samym identyfikatorze
		/// co nauczyciel podany w argumencie <c>teacher</c>.
		/// </summary>
		/// <param name="teacher">Nauczyciel do nadpisania.</param>
		public void Update(Teacher teacher)
		{
			if (teacher == null)
				throw new ArgumentNullException("teacher");
			Teacher teacherToUpdate = this[teacher.TeacherID];
			if (teacherToUpdate == null)
				throw new ArgumentOutOfRangeException("Invalid teacher identifier: " + teacher.TeacherID);

			if (teacher.Address_City != null)
				teacherToUpdate.Address_City = teacher.Address_City;
			if (teacher.Address_Municipality != null)
				teacherToUpdate.Address_Municipality = teacher.Address_Municipality;
			if (teacher.Address_PostCode != null)
				teacherToUpdate.Address_PostCode = teacher.Address_PostCode;
			if (teacher.Address_Street != null)
				teacherToUpdate.Address_Street = teacher.Address_Street;
			if (teacher.BirthDate.HasValue)
				teacherToUpdate.BirthDate = teacher.BirthDate;
			if (teacher.Email != null)
				teacherToUpdate.Email = teacher.Email;
			if (teacher.FirstName != null)
				teacherToUpdate.FirstName = teacher.FirstName;
			if (teacher.IsHeadmaster.HasValue)
				teacherToUpdate.IsHeadmaster = teacher.IsHeadmaster;
			if (teacher.Login != null)
				teacherToUpdate.Login = teacher.Login;
			if (teacher.Password != null)
				teacherToUpdate.Password = teacher.Password;
			if (teacher.PESEL != null)
				teacherToUpdate.PESEL = teacher.PESEL;
			if (teacher.Surname != null)
				teacherToUpdate.Surname = teacher.Surname;

			teacherToUpdate.UpdateDate = DateTime.Now;

			_databaseContext.SaveChanges();
		}
		#endregion
	}
}
